﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using XLua;
using Yoozoo.Gta.Common;

public class NestedScrollRect : ScrollRect
{
    [SerializeField] private ScrollRect parentScroll;

    private bool routeHorizontal = false;
    private bool routeVertical = false;
    private bool routeToParent = false;
    private List<LuaFunction> onEndDragLuaF = new List<LuaFunction>();
    private List<LuaFunction> onBeginDragLuaF = new List<LuaFunction>();
    private List<LuaFunction> onDragLuaF = new List<LuaFunction>();
    private List<LuaFunction> onTouchBeganLuaF = new List<LuaFunction>();

    protected override void Awake()
    {
        base.Awake();
        if (parentScroll != null)
        {
            routeVertical = !this.vertical && this.parentScroll.vertical;
            routeHorizontal = !this.horizontal && this.parentScroll.horizontal;
        }
    }

    public void SetParentScrollRect(ScrollRect rect)
    {
        if (rect)
        {
            parentScroll = rect;
            routeVertical = !this.vertical && this.parentScroll.vertical;
            routeHorizontal = !this.horizontal && this.parentScroll.horizontal;
        }
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began))
        {
#if (UNITY_ANDROID || UNITY_IPHONE) && !UNITY_EDITOR
            if (Input.touchCount > 0 && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#else
            if (EventSystem.current.IsPointerOverGameObject())
#endif
            {
                OnTouchBegan(new PointerEventData(EventSystem.current));
            }
        }
    }

    public void OnTouchBegan(PointerEventData eventData)
    {
        Camera cam = ResidentHandler.Inst.UICamera;
        if (RectTransformUtility.RectangleContainsScreenPoint(gameObject.transform as RectTransform, Input.mousePosition, cam))
        {
            for (var i = 0; i < this.onTouchBeganLuaF.Count; i++)
                this.onTouchBeganLuaF[i].Action(eventData);
        }
    }

    public override void OnDrag(PointerEventData eventData)
    {
        if (routeToParent)
            this.parentScroll.OnDrag(eventData);
        else
            base.OnDrag(eventData);
        
        for (var i = 0; i < this.onDragLuaF.Count; i++)
            this.onDragLuaF[i].Action(eventData);
    }
 
    /// <summary>
    /// Begin drag event
    /// </summary>
    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (routeHorizontal && Math.Abs(eventData.delta.x) > Math.Abs(eventData.delta.y))
            routeToParent = true;
        else if (routeVertical && Math.Abs(eventData.delta.x) < Math.Abs(eventData.delta.y))
            routeToParent = true;
        else
            routeToParent = false;
 
        if (routeToParent)
            this.parentScroll.OnBeginDrag(eventData);
        else
            base.OnBeginDrag(eventData);
        
        for (var i = 0; i < this.onBeginDragLuaF.Count; i++)
            this.onBeginDragLuaF[i].Action(eventData);
    }
 
    /// <summary>
    /// End drag event
    /// </summary>
    public override void OnEndDrag(PointerEventData eventData)
    {
        if (routeToParent)
            this.parentScroll.OnEndDrag(eventData);
        else
            base.OnEndDrag(eventData);

        routeToParent = false;
        for (var i = 0; i < this.onEndDragLuaF.Count; i++)
            this.onEndDragLuaF[i].Action(eventData);
    }
    
    public void AddLuaEndDragEvent(LuaFunction luaFunc)
    {
        this.onEndDragLuaF.Add(luaFunc);
    }

    public void AddLuaBeginDragEvent(LuaFunction luaFunc)
    {
        this.onBeginDragLuaF.Add(luaFunc);
    }

    public void AddLuaDragEvent(LuaFunction luaFunc)
    {
        this.onDragLuaF.Add(luaFunc);
    }

    public void AddLuaTouchBeganEvent(LuaFunction luaFunc)
    {
        this.onTouchBeganLuaF.Add(luaFunc);
    }
    
    protected override void LateUpdate()
    {
        if (transform.lossyScale.x == 0 || transform.lossyScale.y == 0)
            return;
        base.LateUpdate();
    }
}
